package at.ac.univie.zsu.aguataplan.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import at.ac.univie.zsu.aguataplan.domain.Club;
import at.ac.univie.zsu.aguataplan.domain.ClubEMail;
import at.ac.univie.zsu.aguataplan.domain.ClubWeb;

/**
 * @author gerry
 * 
 */
@Repository
public class ClubDaoBean implements ClubDao {

	@PersistenceContext
	transient EntityManager em;

	@Autowired
	private Dao dao;

	// ----------------------------------------------------
	// CONSTRUCTOR
	// ----------------------------------------------------

	public ClubDaoBean() {

	}

	// ----------------------------------------------------
	// METHODS
	// ----------------------------------------------------

	@Override
	@Transactional
	public void cleanClub() throws Exception {
		List<Club> clubs = dao.findAll(Club.class);
		List<ClubEMail> clubEMails = dao.findAll(ClubEMail.class);
		List<ClubWeb> clubWebs = dao.findAll(ClubWeb.class);

		for (Club club : clubs) {
			deleteClub(club.getId());
		}

		for (ClubEMail clubEMail : clubEMails) {
			deleteClubEMail(clubEMail.getId());
		}

		for (ClubWeb clubWeb : clubWebs) {
			deleteClubWeb(clubWeb.getId());
		}

	}

	// --------------

	@Override
	public Club addClub(Club club) throws Exception {
		dao.persist(club);

		return club;
	}

	@Override
	public void deleteClub(long id) throws Exception {
		dao.remove(Club.class, id);
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	// TODO: should not be necessary to have a transaction for a select query
	public List<Club> getClubList() throws Exception {
		List<Club> clubs;
		clubs = em.createQuery("SELECT o FROM " + Club.class.getName() + " o ORDER BY name").getResultList();

		for (Club club : clubs) {
			Hibernate.initialize(club.getRefTeam());
		}

		return clubs;
	}

	@Override
	@Transactional
	public Club getClubById(long id) throws Exception {
		Club club = null;

		club = dao.find(Club.class, id);

		Hibernate.initialize(club.getRefTeam());

		return club;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Club getClubByName(String name) {

		List<Club> clubs = em.createQuery("from " + Club.class.getSimpleName() + " c where c.name like '" + name + "'")
				.getResultList();
		return clubs.get(0);
	}

	@Override
	public Club mergeClub(Club club) throws Exception {
		Club c;
		c = dao.merge(club);

		return c;
	}

	@Override
	public void deleteClubEMail(long id) throws Exception {
		dao.remove(ClubEMail.class, id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ClubEMail> getClubEMailList(Club club) throws Exception {
		List<ClubEMail> clubEMail;
		String query = "SELECT clubEMail FROM Club AS club RIGHT JOIN club.refClubEMail AS clubEMail WHERE club.id = "
				+ club.getId() + " ORDER BY clubEMail.address";
		clubEMail = em.createQuery(query).getResultList();

		return clubEMail;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ClubWeb> getClubWebList(Club club) throws Exception {
		List<ClubWeb> clubWeb;
		String query = "SELECT clubWeb FROM Club AS club RIGHT JOIN club.refClubWeb AS clubWeb WHERE club.id = "
				+ club.getId() + " ORDER BY clubWeb.address";
		clubWeb = em.createQuery(query).getResultList();

		return clubWeb;
	}

	@Override
	public void deleteClubWeb(long id) throws Exception {
		dao.remove(ClubWeb.class, id);
	}

	// ----------------------------------------------------
	// GETTER & SETTER
	// ----------------------------------------------------

	public Dao getDao() {
		return dao;
	}

	public void setDao(Dao dao) {
		this.dao = dao;
	}

}
